package cn.iocoder.yudao.module.social.service.container;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.social.controller.admin.container.vo.ContainerCreateReqVO;
import cn.iocoder.yudao.module.social.controller.admin.container.vo.ContainerPageReqVO;
import cn.iocoder.yudao.module.social.controller.admin.container.vo.ContainerUpdateReqVO;
import cn.iocoder.yudao.module.social.convert.container.ContainerConvert;
import cn.iocoder.yudao.module.social.dal.dataobject.container.ContainerDO;
import cn.iocoder.yudao.module.social.dal.mysql.container.ContainerMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import jakarta.annotation.Resource;
import java.util.Collection;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.social.enums.ErrorCodeConstants.CONTAINER_NOT_EXISTS;
import static cn.iocoder.yudao.module.social.enums.ErrorCodeConstants.CONTAINER_NAME_EXISTS;

/**
 * 容器 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
@Slf4j
public class ContainerServiceImpl implements ContainerService {

    @Resource
    private ContainerMapper containerMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createContainer(ContainerCreateReqVO createReqVO) {
        // 校验名称唯一
        validateContainerNameUnique(null, createReqVO.getName());
        
        // 插入
        ContainerDO container = ContainerConvert.INSTANCE.convert(createReqVO);
        containerMapper.insert(container);
        // 返回
        return container.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateContainer(ContainerUpdateReqVO updateReqVO) {
        // 校验存在
        validateContainerExists(updateReqVO.getId());
        // 校验名称唯一
        validateContainerNameUnique(updateReqVO.getId(), updateReqVO.getName());
        
        // 更新
        ContainerDO updateObj = ContainerConvert.INSTANCE.convert(updateReqVO);
        containerMapper.updateById(updateObj);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteContainer(Long id) {
        // 校验存在
        validateContainerExists(id);
        // 删除
        containerMapper.deleteById(id);
    }

    private void validateContainerExists(Long id) {
        if (containerMapper.selectById(id) == null) {
            throw exception(CONTAINER_NOT_EXISTS);
        }
    }

    private void validateContainerNameUnique(Long id, String name) {
        ContainerDO container = containerMapper.selectByName(name);
        if (container == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的容器
        if (id == null) {
            throw exception(CONTAINER_NAME_EXISTS);
        }
        if (!container.getId().equals(id)) {
            throw exception(CONTAINER_NAME_EXISTS);
        }
    }

    @Override
    public ContainerDO getContainer(Long id) {
        return containerMapper.selectById(id);
    }

    @Override
    public List<ContainerDO> getContainerList(Collection<Long> ids) {
        return containerMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<ContainerDO> getContainerPage(ContainerPageReqVO pageReqVO) {
        return containerMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ContainerDO> getContainerListByType(String type) {
        return containerMapper.selectListByType(type);
    }

    @Override
    public List<ContainerDO> getContainerListByParent(Long parentId) {
        return containerMapper.selectListByParentId(parentId);
    }

    @Override
    public List<ContainerDO> getContainerListByCreator(String creator) {
        return containerMapper.selectListByCreator(creator);
    }

    @Override
    public List<ContainerDO> getContainerTree(String type) {
        // 获取所有根容器（parentId 为 null）
        List<ContainerDO> rootContainers = containerMapper.selectListByParentIdAndType(null, type);
        // 递归构建树形结构
        return buildContainerTree(rootContainers, type);
    }

    @Override
    public List<ContainerDO> getPublicContainerList(String type) {
        // 这里可以根据业务需求定义什么是"公开"容器
        // 例如：系统预设的容器、公开可见的容器等
        return containerMapper.selectPublicListByType(type);
    }

    /**
     * 递归构建容器树形结构
     */
    private List<ContainerDO> buildContainerTree(List<ContainerDO> containers, String type) {
        for (ContainerDO container : containers) {
            List<ContainerDO> children = containerMapper.selectListByParentIdAndType(container.getId(), type);
            if (!children.isEmpty()) {
                // 递归构建子树
                buildContainerTree(children, type);
                // 这里可以设置children到container中，如果ContainerDO有children字段的话
            }
        }
        return containers;
    }

    @Override
    public void validateContainerList(Collection<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return;
        }
        
        List<ContainerDO> containers = containerMapper.selectBatchIds(ids);
        if (containers.size() != ids.size()) {
            throw exception(CONTAINER_NOT_EXISTS);
        }
    }

}
